#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void preencher_tabela(int *T);
void switchTab(int l, int *T);
void Acha_z(int p, int *Z, int *T);
void repete_k(int k,int* Z, int* T);


int main(int argc, char* argv[])
{
	int T[1000], Z[4],k;
	//int k = (int)*argv[1];
	if (argc < 2) 
	{
        printf("Deverá introduzir o numero de numeros a gerar\n");
        return 0;
    }
	sscanf (argv[1],"%d",&k);

	repete_k(k, Z, T);
	
	return 0;
}

/*******************
 * Função para gerar 1000 digitos aleatorios dentro de uma Tabela T
 * ********************************/
void preencher_tabela(int *T) //Recebe a localização de memoria da zona da tablea T (ponteiro) fazendo as alterações na mesma
{
	int j=0,x;
	int tab_contagem[10];
	srand ((unsigned)time( NULL ));
	for (j=0;j<1000;j++)
	{
		
		x = (rand() % 10); //Cria um digito de 0 a 9 de forma aleatoria
		
		if (tab_contagem[x]<100) //Vai conferir na tabela de contagem se esse digito já foi usado 100 x
		{
			tab_contagem[x]+=1; //Se não irá então adicionar mais uma entrada à tabela de contagem
			T[j]=x; //Adiciona o digito em questão à tabela T (Principal de 1000 digitos)
		}
		else
		{
			j--; //Caso o digito ja tenha 100 elementos, volta a repetir a interação para a posição j da tabela T
		}
	}
	return;
	
}

/*******************
 * Função para Permutar os valores de Tl com T0
 * ********************************/
void switchTab(int l, int* T) 
{
        int aux=0;
                
        aux = T[l];
        T[l] = T[0];
        T[0] = aux;
        return;
}

/*********************************
 * Função para Preencher uma Tabela Z com os valores de Z1, Z2, Z3 e Z4 segundo a formula do enunciado
 * ********************************/
void Acha_z(int p, int* Z, int* T)
{
    int j,l;
  
    for (j=1; j<=4; j++)
    {
        if (p<1000-j)
        {
            l=p+j;
		}
        else
        {
            l=0;
		}
                
        Z[j]=T[l]; //Atribui à posição j da tablea dos Z o valor da posição l da tabela dos T
        
        switchTab(l, T); // Faz o switch dos valores na tabela T (T0 <-> Tl)
    }
    return;
}

/*********************************
 * Função para repetir o processo para a quantidade de numeros aleatorios pretendidos
 * ********************************/

void repete_k(int k, int* Z, int* T)
{
    int N[k],p,i;
    preencher_tabela(T);
    p = (rand() % 1000); //Cria um numero p pseudo aleatorio 0...999
    for (i=1; i<=k;i++)
    {
        Acha_z(p, Z, T); //Chama a função para achar os Z pretendidos para os calculos
        
        N[i] = Z[1]<<12|Z[2]<<8|Z[3]<<4|Z[4]; //Preenche a tabela N com a quantidade de numeros pretendidos a ser gerados (passados por paramentro)
        printf("N %d - %d\n",i, N[i]);
        p=Z[1]*100+Z[2]*10+Z[3]*1;
   	}
   	return;
}

